package com.ruoyi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.entity.DecorationRecord;
import com.ruoyi.mapper.DecorationRecordMapper;
import com.ruoyi.service.DecorationRecordService;
import com.ruoyi.service.FileStorageService;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.*;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Base64;

/**
 * 装饰记录服务实现类
 *
 * @author ruoyi
 */
@Service
@Slf4j
public class DecorationRecordServiceImpl extends ServiceImpl<DecorationRecordMapper, DecorationRecord> implements DecorationRecordService {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${aliyun.ai.endpoint}")
    private String aiEndpoint;

    @Value("${aliyun.dashscope.api-key}")
    private String apiKey;

    @Value("${aliyun.ai.appId}")
    private Integer appId;

    /**
     * 根据用户ID获取装饰记录列表
     *
     * @param userId 用户ID
     * @return 装饰记录列表，按创建时间降序排列
     */
    @Override
    public List<DecorationRecord> listRecordsByUserId(String userId) {
        LambdaQueryWrapper<DecorationRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DecorationRecord::getUserId, userId)
                .orderByDesc(DecorationRecord::getCreatedAt);
        return list(wrapper);
    }

    /**
     * 根据记录ID获取装饰记录
     *
     * @param id 记录ID
     * @return 装饰记录对象
     */
    @Override
    public DecorationRecord getRecordById(Integer id) {
        return getById(id);
    }

    /**
     * 获取装饰记录详情
     *
     * @param id 记录ID
     * @return 装饰记录对象
     * @implNote 可以在此方法中添加额外的关联数据查询，如果只是获取基本记录信息，可以直接调用getById方法
     */
    @Override
    public DecorationRecord getRecordDetail(Integer id) {
        // 这里实现获取装饰记录详情的逻辑，可以添加额外的关联数据查询
        // 如果只是获取基本记录信息，可以直接调用getById方法
        return getById(id);
    }

    /**
     * 创建装饰记录
     *
     * @param record 装饰记录对象
     * @return 是否成功创建记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createRecord(DecorationRecord record) {
        record.setCreatedAt(LocalDateTime.now());
        record.setUpdatedAt(LocalDateTime.now());
        if (record.getStatus() == null) {
            record.setStatus(2); // 默认为生成中
        }
        return save(record);
    }

    /**
     * 更新装饰记录
     *
     * @param record 装饰记录对象
     * @return 是否成功更新记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRecord(DecorationRecord record) {
        record.setUpdatedAt(LocalDateTime.now());
        return updateById(record);
    }

    /**
     * 删除装饰记录
     *
     * @param id 记录ID
     * @return 是否成功删除记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteRecord(Integer id) {
        return removeById(id);
    }

    /**
     * 获取用户最新的装饰记录列表
     *
     * @param userId 用户ID
     * @param limit  返回记录的数量限制
     * @return 最新的装饰记录列表，按创建时间降序排列
     */
    @Override
    public List<DecorationRecord> getLatestRecords(String userId, Integer limit) {
        LambdaQueryWrapper<DecorationRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DecorationRecord::getUserId, userId)
                .orderByDesc(DecorationRecord::getCreatedAt)
                .last("LIMIT " + limit);
        return list(wrapper);
    }

    /**
     * 获取用户的分页装饰记录
     *
     * @param userId   用户ID
     * @param page     当前页码
     * @param pageSize 每页记录数
     * @return 分页后的装饰记录列表，按创建时间降序排列
     */
    @Override
    public IPage<DecorationRecord> getUserRecords(Integer userId, Integer page, Integer pageSize) {
        Page<DecorationRecord> pageParam = new Page<>(page, pageSize);
        LambdaQueryWrapper<DecorationRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DecorationRecord::getUserId, userId)
                .orderByDesc(DecorationRecord::getCreatedAt);
        return page(pageParam, wrapper);
    }

    /**
     * 生成装饰记录的预览图
     *
     * @param record 装饰记录对象
     * @return 预览图的URL
     * @implNote TODO: 实现预览图生成逻辑
     * 1. 根据房间模板和风格模板生成3D场景
     * 2. 渲染预览图
     * 3. 保存预览图并返回URL
     */
    @Override
    public String generatePreview(DecorationRecord record) {
        try {
            // 1. 检查记录状态
            if (record.getStatus() == null) {
                throw new RuntimeException("记录状态异常");
            }

            // 如果记录状态不是成功，则无法生成预览
            if (record.getStatus() != 1) {
                throw new RuntimeException("图片生成未完成或失败，无法创建预览");
            }

            // 2. 检查预览图URL
            if (record.getPreviewImageUrl() != null && !record.getPreviewImageUrl().trim().isEmpty()) {
                return record.getPreviewImageUrl();
            }

            // 3. 检查生成图片URL
            if (record.getResultImageUrl() == null || record.getResultImageUrl().trim().isEmpty()) {
                throw new RuntimeException("没有可用的生成图片，无法创建预览");
            }

            // 4. 检查房间信息
            String roomImageUrl = record.getCustomRoomUrl();
            if (roomImageUrl == null || roomImageUrl.trim().isEmpty()) {
                // 如果没有自定义房间图片，使用模板房间图片
                if (record.getRoomId() != null) {
                    // TODO: 从房间模板获取图片URL
                    // roomImageUrl = roomTemplateService.getRoomImageUrl(record.getRoomId());
                }
            }

            // 5. 生成预览图
            String previewUrl;
            if (roomImageUrl != null && !roomImageUrl.trim().isEmpty()) {
                // TODO: 如果有房间图片，合成预览效果图
                // previewUrl = imageProcessService.compositeImages(roomImageUrl, record.getResultImageUrl());
                previewUrl = record.getResultImageUrl(); // 临时使用生成图片作为预览
            } else {
                // 如果没有房间图片，直接使用生成的图片
                previewUrl = record.getResultImageUrl();
            }

            // 6. 更新记录
            record.setPreviewImageUrl(previewUrl);
            record.setUpdatedAt(LocalDateTime.now());
            updateById(record);

            return previewUrl;
        } catch (Exception e) {
            log.error("生成预览图失败", e);
            throw new RuntimeException("生成预览图失败：" + e.getMessage());
        }
    }

    /**
     * 更新装饰记录的状态
     *
     * @param id           记录ID
     * @param status       状态码
     * @param errorMessage 错误信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Integer id, Integer status, String errorMessage) {
        DecorationRecord record = new DecorationRecord();
        record.setId(id);
        record.setStatus(status);
        record.setErrorMessage(errorMessage);
        record.setUpdatedAt(LocalDateTime.now());
        updateById(record);
    }


    @Autowired
    private FileStorageService fileStorageService;

    /**
     * 上传图片文件
     * @param file
     * @return
     */
    @Override
    public String uploadImageFile(MultipartFile file) throws IOException, ServerException, InvalidBucketNameException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        if(file==null || file.getSize()<0){
            return "";
        }
        String s = fileStorageService.uploadImageFile(file.getOriginalFilename(), file.getInputStream());
        return s;
    }

    /**
     * 上传图片并使用阿里云百炼AI生成新图片
     * @param file 原始图片文件
     * @return 生成的图片URL
     */
    @Override
    public String uploadAndGenerateImage(MultipartFile file) throws Exception {
        // 1. 首先将原始图片上传到MinIO
        String originalImageUrl = uploadImageFile(file);

        // 2. 将图片转换为Base64
        byte[] imageBytes = file.getBytes();
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);

        // 3. 调用阿里云百炼AI接口生成新图片
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Bearer " + apiKey);

        Map<String, Object> input = new HashMap<>();
        input.put("image", base64Image);

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("style", "anime"); // 设置为动漫风格
        parameters.put("seed", System.currentTimeMillis()); // 随机种子
        parameters.put("size", "1024x1024"); // 图片尺寸

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "wanx-v1"); // 使用通义万相模型
        requestBody.put("input", input);
        requestBody.put("parameters", parameters);

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);

        ResponseEntity<Map> response = restTemplate.exchange(
            aiEndpoint + "/services/aigc/image2image/generation",
            HttpMethod.POST,
            requestEntity,
            Map.class
        );

        // 4. 解析响应，获取生成的图片数据
        Map<String, Object> responseBody = response.getBody();
        Map<String, Object> output = (Map<String, Object>) responseBody.get("output");
        String generatedImageBase64 = (String) output.get("image");

        // 5. 将生成的图片保存到MinIO
        byte[] generatedImageBytes = Base64.getDecoder().decode(generatedImageBase64);
        String fileName = "generated_" + System.currentTimeMillis() + ".png";
        return fileStorageService.uploadImageBytes(fileName, generatedImageBytes);
    }

    /**
     * 根据文本描述生成图片
     * @param prompt 文本描述
     * @return 生成的图片URL
     */
    @Override
    public String generateImageFromText(String prompt) throws Exception {
        // 1. 准备请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Bearer " + apiKey);

        // 2. 准备请求体
        Map<String, Object> input = new HashMap<>();
        input.put("prompt", prompt);

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("style", "anime"); // 设置为动漫风格
        parameters.put("size", "1024x1024"); // 图片尺寸
        parameters.put("n", 1); // 生成图片数量
        parameters.put("seed", System.currentTimeMillis()); // 随机种子

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "wanx-v1"); // 使用通义万相模型
        requestBody.put("input", input);
        requestBody.put("parameters", parameters);

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);

        // 3. 调用阿里云百炼AI接口
        ResponseEntity<Map> response = restTemplate.exchange(
            aiEndpoint + "/services/aigc/text2image/generation",
            HttpMethod.POST,
            requestEntity,
            Map.class
        );

        // 4. 解析响应
        Map<String, Object> responseBody = response.getBody();
        Map<String, Object> output = (Map<String, Object>) responseBody.get("output");
        String generatedImageBase64 = (String) output.get("image");

        // 5. 将生成的图片保存到MinIO
        byte[] generatedImageBytes = Base64.getDecoder().decode(generatedImageBase64);
        String fileName = "text2img_" + System.currentTimeMillis() + ".png";
        return fileStorageService.uploadImageBytes(fileName, generatedImageBytes);
    }
}
